#!/bin/bash
set -e

TOP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd )"
SCRIPTS_DIR="${TOP_DIR}/scripts"
PACKAGE_HARVESTER_OS_DIR="${TOP_DIR}/package/harvester-os"
PACKAGE_HARVESTER_REPO_DIR="${TOP_DIR}/package/harvester-repo"

cd ${TOP_DIR}

source ${SCRIPTS_DIR}/version
source ${SCRIPTS_DIR}/version-rke2
source ${SCRIPTS_DIR}/version-rancher
source ${SCRIPTS_DIR}/lib/http
source ${SCRIPTS_DIR}/lib/image

BUNDLE_DIR="${PACKAGE_HARVESTER_OS_DIR}/iso/bundle"
CHARTS_DIR="${PACKAGE_HARVESTER_REPO_DIR}/charts"
IMAGES_DIR="${BUNDLE_DIR}/harvester/images"
RANCHERD_IMAGES_DIR="${BUNDLE_DIR}/rancherd/images"

mkdir -p ${CHARTS_DIR}
mkdir -p ${IMAGES_DIR}
mkdir -p ${RANCHERD_IMAGES_DIR}

# Prepare Harvester chart
harvester_path=../harvester
if [ ! -d ${harvester_path} ];then
    echo "No existed harvester source. Pulling into /tmp/harvester"
    git clone --branch master --single-branch --depth 1 https://github.com/harvester/harvester.git /tmp/harvester
    harvester_path=/tmp/harvester
fi

# This must be placed after cloning `harvester/harvester`` in case `make build-bundle` is run directly.
source ${SCRIPTS_DIR}/version-harvester ${TOP_DIR}/../harvester

harvester_chart_path=${harvester_path}/deploy/charts/harvester
harvester_crd_chart_path=${harvester_path}/deploy/charts/harvester-crd
helm package ${harvester_chart_path} -d ${CHARTS_DIR}
helm package ${harvester_crd_chart_path} -d ${CHARTS_DIR}

# Prepare monitoring chart
source ${SCRIPTS_DIR}/version-monitoring
helm pull https://charts.rancher.io/assets/rancher-monitoring-crd/rancher-monitoring-crd-${MONITORING_VERSION}.tgz -d ${CHARTS_DIR}
helm pull https://charts.rancher.io/assets/rancher-monitoring/rancher-monitoring-${MONITORING_VERSION}.tgz -d ${CHARTS_DIR}

# make chart sanity check
tar zxvf ${CHARTS_DIR}/rancher-monitoring-crd-${MONITORING_VERSION}.tgz >/dev/null
tar zxvf ${CHARTS_DIR}/rancher-monitoring-${MONITORING_VERSION}.tgz >/dev/null

# Create Helm repo index after charts are ready
helm repo index ${CHARTS_DIR}

if [ -n "$HARVESTER_INSTALLER_OFFLINE_BUILD" -a -e /bundle ]; then
 cp -rf /bundle/* ${BUNDLE_DIR}/
 exit 0
fi

# Offline images

# Rancherd bootstrap images
image_list_file=${RANCHERD_IMAGES_DIR}/rancherd-bootstrap-images-${VERSION}.txt
cp ${SCRIPTS_DIR}/images/rancherd-bootstrap-images.txt $image_list_file
RKE2_VERSION_NORMALIZED=${RKE2_VERSION/+/-} # v1.21.3-rc6+rke2r2 -> v1.21.3-rc6-rke2r2
sed -i "s,\$RKE2_VERSION,${RKE2_VERSION_NORMALIZED}," ${image_list_file}
save_image "agent" $BUNDLE_DIR ${image_list_file} ${RANCHERD_IMAGES_DIR}

# Rancher images
image_list_file=${IMAGES_DIR}/rancher-images-${RANCHER_VERSION}.txt
cp ${SCRIPTS_DIR}/images/rancher-images.txt $image_list_file
save_image "common" $BUNDLE_DIR $image_list_file ${IMAGES_DIR}

# RKE2 images
RKE2_IMAGES_URL="https://github.com/rancher/rke2/releases/download/${RKE2_VERSION}"
image_list_file="${IMAGES_DIR}/rke2-images.linux-amd64-${RKE2_VERSION_NORMALIZED}.txt"
image_archive="${IMAGES_DIR}/rke2-images.linux-amd64-${RKE2_VERSION_NORMALIZED}.tar.zst"
get_url "${RKE2_IMAGES_URL}/rke2-images.linux-amd64.txt" $image_list_file
get_url "${RKE2_IMAGES_URL}/rke2-images.linux-amd64.tar.zst" $image_archive
add_image_list_to_metadata "rke2" $BUNDLE_DIR $image_list_file $image_archive

# exclude SR-IOV images
image_list_file="${IMAGES_DIR}/rke2-images-multus.linux-amd64-${RKE2_VERSION_NORMALIZED}.txt"
# save_image_list "rke2-images-multus" "${RKE2_IMAGES_URL}/rke2-images-multus.linux-amd64.txt" ${IMAGES_DIR}/rke2-images-multus.linux-amd64.txt
# Workaround for https://github.com/rancher/rke2/issues/2229
cat > $image_list_file <<EOF
docker.io/rancher/hardened-cni-plugins:v0.9.1-build20211119
docker.io/rancher/hardened-multus-cni:v3.7.1-build20211119
EOF

save_image "rke2" $BUNDLE_DIR $image_list_file ${IMAGES_DIR}

# Harvester images: get image list from harvester chart's values file
image_list_file="harvester-images-${VERSION}.txt"
values_file="${harvester_chart_path}/values.yaml"
touch ${image_list_file}
repositories=( $(yq eval ' explode(.) | .. | select(has("repository")) |select(has("tag")) | .repository' ${values_file}) )
tags=( $(yq eval ' explode(.) | .. | select(has("repository")) |select(has("tag")) | .tag' ${values_file}) )
repositories_length=${#repositories[@]}
tags_length=${#tags[@]}
if [ ${repositories_length} -ne ${tags_length} ];then
  echo "The number of image repositories does not match the number of image tags";
  exit 1
fi
for i in "${!repositories[@]}"; do
  echo "${repositories[$i]}:${tags[$i]}">>${image_list_file}
done
# The following images are not included in chart or Longhorn image list
cat <<EOF >> ${image_list_file}
busybox:1.32.0
alpine:3
registry.suse.com/suse/vmdp/vmdp:2.5.3
EOF

# get longhorn image list
longhorn_version=v$(ls ${harvester_chart_path}/charts | grep longhorn| sed -e "s/^longhorn-//" -e "s/.tgz$//")
longhorn_image_url=https://raw.githubusercontent.com/longhorn/longhorn/${longhorn_version}/deploy/longhorn-images.txt
curl ${longhorn_image_url}>>${image_list_file}

# format image list
awk -F ':' '{if($2==""){print $1":latest"}else{print $0}}' "${image_list_file}" | \
awk -F '/' '{if(NF>=3){print $0} else if(NF==2){print "docker.io/"$0}else if(NF==1){print "docker.io/library/"$0}}' >"${image_list_file}.tmp"

# clean image list
sort -u "${image_list_file}.tmp" | \
grep -Ev "local-path-provisioner|library-traefik|klipper-lb|multus" >"${image_list_file}"

cp ${image_list_file} ${IMAGES_DIR}
save_image "common" $BUNDLE_DIR ${IMAGES_DIR}/${image_list_file} ${IMAGES_DIR}

# Tag harvester-upgrade:master-head to harvester-upgrade:<version> and save the image to an archive
# This makes it possible to upgrade a cluster with a master ISO.
upgrade_image_repo=$(yq -e e '.upgrade.image.repository' $values_file)
upgrade_image_tag=$(yq -e e '.upgrade.image.tag' $values_file)
if [ "$upgrade_image_tag" != "$HARVESTER_VERSION" ]; then
  docker tag "${upgrade_image_repo}:${upgrade_image_tag}" "${upgrade_image_repo}:${HARVESTER_VERSION}"
  image_list_file="${IMAGES_DIR}/harvester-extra-${VERSION}.txt"
  image_archive="${IMAGES_DIR}/harvester-extra-${VERSION}.tar"
  echo "docker.io/${upgrade_image_repo}:${HARVESTER_VERSION}" > ${image_list_file}
  docker image save -o $image_archive $(<$image_list_file)
  zstd --rm $image_archive -o "${image_archive}.zst"
  add_image_list_to_metadata "common" $BUNDLE_DIR $image_list_file "${image_archive}.zst"
fi
